#!/bin/python

#
#Xithyl, Test Driven Development for C
#Copyright (C) 2012  Stepan Henek
#
#This program is free software: you can redistribute it and/or modify
#it under the terms of the GNU General Public License as published by
#the Free Software Foundation, either version 3 of the License, or
#(at your option) any later version.
#
#This program is distributed in the hope that it will be useful,
#but WITHOUT ANY WARRANTY; without even the implied warranty of
#MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
#GNU General Public License for more details.
#
#You should have received a copy of the GNU General Public License
#along with this program.  If not, see <http://www.gnu.org/licenses/>.
#

from xithyl import logger
from xithyl.Ctypes.basic import *
from xithyl.Ctypes import libc
from xithyl.conditions import basic
from xithyl import actions
from ctypes import *

logger.addLogger(__name__)

def functional1():
    """
    Creates two strings.
    Concatenate them using strncat the second string is smaller then n parameter.
    Test the result.
    """

    result = True

    logger.log("Functional 1", __name__)

    logger.log("Init string1", __name__)

    str1 = makeArray(30, ord('0'))
    str1 = cast(str1, c_char_p)

    string1 = "This test is"

    setStringInArray(str1, 0, string1)

    # Test assignment
    result &= basic.arrayEqualsLen(map(lambda x: ord(x), string1) + [ 0 ] + [ ord('0') ] * (30 - len(string1) - 1), charArrayToList(str1, 30), 30, __name__, True)

    logger.log("Init string2", __name__)
    str2 = makeArray(30, ord('1'))
    str2 = cast(str2, c_char_p)

    string2 = " done."

    setStringInArray(str2, 0, string2)

    # Test assignment
    result &= basic.arrayEqualsLen(map(lambda x: ord(x), string2) + [ 0 ] + [ ord('1') ] * (30 - len(string2) - 1), charArrayToList(str2, 30), 30, __name__, True)

    logger.log("concatenate strings -> \"%s%s\"" % (str1.value, str2.value), __name__)

    # Call memcpy
    target = libc.string.strncat(str1, str2, len(string2) + 1)

    logger.log("concatenated into %x" % getReferencedAddress(target), __name__)

    rstring = string1 + string2
    result &= basic.arrayEqualsLen(map(lambda x: ord(x), rstring) + [ 0 ] + [ ord('0') ] * (30 - len(rstring) - 1), charArrayToList(str1, 30), 30, __name__, True)

    logger.log("Functional 1 done", __name__)

    return result

def functional2():
    """
    Creates two strings.
    Concatenate them using strncat the second string is bigger then n parameter.
    Test the result.
    """

    result = True

    logger.log("Functional 2", __name__)

    logger.log("Init string1", __name__)

    str1 = makeArray(30, ord('0'))
    str1 = cast(str1, c_char_p)

    string1 = "This test is"

    setStringInArray(str1, 0, string1)

    # Test assignment
    result &= basic.arrayEqualsLen(map(lambda x: ord(x), string1) + [ 0 ] + [ ord('0') ] * (30 - len(string1) - 1), charArrayToList(str1, 30), 30, __name__, True)

    logger.log("Init string2", __name__)
    str2 = makeArray(30, ord('1'))
    str2 = cast(str2, c_char_p)

    string2 = " done."

    setStringInArray(str2, 0, string2)

    # Test assignment
    result &= basic.arrayEqualsLen(map(lambda x: ord(x), string2) + [ 0 ] + [ ord('1') ] * (30 - len(string2) - 1), charArrayToList(str2, 30), 30, __name__, True)

    logger.log("concatenate strings -> \"%s%s\"" % (str1.value, str2.value), __name__)

    # Call memcpy
    target = libc.string.strncat(str1, str2, len(string2) - 1)

    logger.log("concatenated into %x" % getReferencedAddress(target), __name__)

    rstring = string1 + string2[:len(string2) - 1]
    result &= basic.arrayEqualsLen(map(lambda x: ord(x), rstring) + [ 0 ] + [ ord('0') ] * (30 - len(rstring) - 1), charArrayToList(str1, 30), 30, __name__, True)

    logger.log("Functional 2 done", __name__)

    return result
